package com.atguigu.classroom.wechat.service.impl;

import com.atguigu.classroom.CourseClient.CourseFeignClient;
import com.atguigu.classroom.model.vod.Course;
import com.atguigu.classroom.wechat.service.MessageService;
import com.atguigu.classroom.wechat.utils.SHA1;
import com.atguigu.classroom.wechat.utils.WeChatPropertiesUtils;
import lombok.SneakyThrows;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.*;

@Service
public class MessageServiceImpl implements MessageService {
    @Autowired
    private CourseFeignClient courseFeignClient;
    @Autowired
    private WxMpService wxMpService;
    @Override
    public String verifyToken(HttpServletRequest request) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        if(this.checkSignature(signature,timestamp,nonce, WeChatPropertiesUtils.TOKEN)){
            return echostr;
        }else {
            return null;
        }
    }
    //验证消息的确来自微信服务器方法
    private boolean checkSignature(String signature,String timestamp,String nonce,String token){
        String[] sig=new String[]{timestamp,nonce,token};
        Arrays.sort(sig);
        if(signature.equals(SHA1.encode(sig[0]+sig[1]+sig[2]))){
            return true;
        }else {
            return false;
        }
    }
    @Override
    public String receiveMessage(HttpServletRequest request){
        String content="";
        Map<String, String> param=new HashMap<>();
        try {
            param = parseXml(request);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String msgType = param.get("MsgType");//消息类型
        switch (msgType){
            case "text"://普通文本类型
                content=search(param);
                break;
            case "event"://事件类型,比如关注,取消关注,点击“关于我们”
                String event = param.get("Event");
                String eventKey = param.get("EventKey");
                if("subscribe".equals(event)) {//关注公众号
                    content = this.subscribe(param);
                } else if("unsubscribe".equals(event)) {//取消关注公众号
                    content = this.unsubscribe(param);
                } else if("CLICK".equals(event) && "aboutUs".equals(eventKey)){//点击关于我们
                    content = this.aboutUs(param);
                } else {
                    content = "success";
                }
                break;
            default:
                content = "success";
        }
        return content;
    }
    //将输入内容解析为map集合
    private Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        InputStream inputStream = request.getInputStream();
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        Element root = document.getRootElement();
        List<Element> elementList = root.elements();
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        inputStream.close();
        inputStream = null;
        return map;
    }
    //普通文本类型：处理关键字搜索事件
    private String search(Map<String, String> param) {
        String fromusername = param.get("FromUserName");
        String tousername = param.get("ToUserName");
        String content = param.get("Content");
        Long createTime = new Date().getTime() / 1000;//单位为秒，不是毫秒
        StringBuffer text = new StringBuffer();
        List<Course> courseList = courseFeignClient.findByKeyword(content);
        if(CollectionUtils.isEmpty(courseList)) {
            text = this.text(param, "请重新输入关键字，没有匹配到相关视频课程");
        } else {//一次只能返回一个
            Random random = new Random();
            int num = random.nextInt(courseList.size());
            Course course = courseList.get(num);
            StringBuffer articles = new StringBuffer();
            articles.append("<item>");
            articles.append("<Title><![CDATA["+course.getTitle()+"]]></Title>");
            articles.append("<Description><![CDATA["+course.getTitle()+"]]></Description>");
            articles.append("<PicUrl><![CDATA["+course.getCover()+"]]></PicUrl>");
            articles.append("<Url><![CDATA[http://glkt.atguigu.cn/#/liveInfo/"+course.getId()+"]]></Url>");
            articles.append("</item>");
            text.append("<xml>");
            text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");
            text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");
            text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");
            text.append("<MsgType><![CDATA[news]]></MsgType>");
            text.append("<ArticleCount><![CDATA[1]]></ArticleCount>");
            text.append("<Articles>");
            text.append(articles);
            text.append("</Articles>");
            text.append("</xml>");
        }
        return text.toString();
    }
    //事件类型：点击事件-关于我们
    private String aboutUs(Map<String, String> param) {
        return this.text(param, "硅谷课堂现开设Java、HTML5前端+全栈、大数据、全链路UI/UE设计、人工智能、大数据运维+Python自动化、Android+HTML5混合开发等多门课程；同时，通过视频分享、谷粒学苑在线课堂、大厂学苑直播课堂等多种方式，满足了全国编程爱好者对多样化学习场景的需求，已经为行业输送了大量IT技术人才。").toString();
    }
    //事件类型：处理关注事件
    private String subscribe(Map<String, String> param) {
        return this.text(param, "感谢你关注“硅谷课堂”，可以根据关键字搜索您想看的视频教程，如：JAVA基础、Spring boot、大数据等").toString();
    }
    //事件类型：处理取消关注事件
    private String unsubscribe(Map<String, String> param) {
        return "success";
    }
    //回复文本
    private StringBuffer text(Map<String, String> param, String content) {
        String fromusername = param.get("FromUserName");
        String tousername = param.get("ToUserName");
        Long createTime = new Date().getTime() / 1000;//单位为秒，不是毫秒
        StringBuffer text = new StringBuffer();
        text.append("<xml>");
        text.append("<ToUserName><![CDATA["+fromusername+"]]></ToUserName>");
        text.append("<FromUserName><![CDATA["+tousername+"]]></FromUserName>");
        text.append("<CreateTime><![CDATA["+createTime+"]]></CreateTime>");
        text.append("<MsgType><![CDATA[text]]></MsgType>");
        text.append("<Content><![CDATA["+content+"]]></Content>");
        text.append("</xml>");
        return text;
    }
    @SneakyThrows
    @Override
    public void pushPayMessage(long id) {
        String openid = "oALpy6GQsaYZGmDkzMm1hNWjlgqs";
        WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                .toUser(openid)//要推送的用户openid
                .templateId("pQAZC0PYpjzeek0iIECm4DUD5vyB5-7YN5n_xA1Rgbs")//模板id
                .url("http://ggkt2.vipgz1.91tunnel.com/#/pay/"+id)//点击模板消息要访问的网址
                .build();
        //3,如果是正式版发送消息，，这里需要配置你的信息
        templateMessage.addData(new WxMpTemplateData("first", "亲爱的用户：您有一笔订单支付成功。", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword1", "1314520", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword2", "java基础课程", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword3", "2022-01-11", "#272727"));
        templateMessage.addData(new WxMpTemplateData("keyword4", "100", "#272727"));
        templateMessage.addData(new WxMpTemplateData("remark", "感谢你购买课程，如有疑问，随时咨询！", "#272727"));
        String msg = wxMpService.getTemplateMsgService().sendTemplateMsg(templateMessage);
        System.out.println(msg);
    }
}
